Skip to content

perf: optimize metadata generator - #52

Open
DjDeveloperr wants to merge 275 commits into
refactorfrom
optimize-metadata-generator
Open

perf: optimize metadata generator#52
DjDeveloperr wants to merge 275 commits into
refactorfrom
optimize-metadata-generator

Conversation

@DjDeveloperr

Copy link
Copy Markdown
Collaborator

No description provided.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 763921be-9832-450c-9e2b-281a8690e780

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Move the expando lookup to the very first check in
NativeApiObjectHostObject::get(), before the 18 string comparisons
for special properties. This eliminates ~100-180ns of wasted string
comparisons on every method call (the hot path).

Also skip Symbol properties early in the V8 interceptor callback
to avoid unnecessary UTF8 conversion.

Benchmark: 1232ms total (was 1372ms) — 10% improvement.
Per-case: respondsToSelector 207ns (was 246ns), characterAtIndex 200ns (was 228ns).
Tests: v8 713/0
- Skip redundant sel_registerName + class_getInstanceMethod when the
  prepared invocation is already cached (first-call-only overhead).
- Use raw pointer for receiver host object lookup (avoids atomic
  ref count increment on every method call).
- Only acquire shared_ptr for init methods that need disown handling.
- Add v8HostObjectRaw<T> template for zero-overhead receiver access.

Tests: v8 713/0
Switch V8 HostObject interceptor from kNone to kNonMasking. With
kNonMasking, V8 checks own properties and prototype chain BEFORE
calling the interceptor. This means method calls and property getters
installed on the prototype (by installClassMembers) are found directly
by V8's inline caches without any C++ interceptor overhead.

Add toString to the host object template so it overrides
Object.prototype.toString (which would otherwise shadow it with
kNonMasking).

Benchmark: 732ms total (was 1250ms) — 42% improvement, now matching
legacy iOS V8 performance (728ms).

Known: 9 test failures related to function pointer resolution,
instanceof, and readonly property error messages. These are edge cases
that need the interceptor but aren't on the hot path.

Tests: 713 total, 9 failures (704 pass)
Add a separate V8 object template for NativeApiObjectHostObject that
uses kNonMasking interceptor flag. This allows V8 to check the
prototype chain before calling the interceptor for native object
instances, enabling faster property access for methods and getters
installed on the prototype.

Also skip superclass/class/constructor/debugDescription from prototype
property installation so the interceptor's special handling is used
(these properties need to return wrapped class constructors).

Install toString on the native object template to override
Object.prototype.toString with kNonMasking.

Tests: v8 713/0
Use kNonMasking interceptor on native object instances only (not class
or bridge host objects). This allows V8 to find prototype properties
without calling the interceptor, giving a 40% speedup.

Benchmark: 773ms (was 1250ms)
Tests: 713 total, 7 failures remaining (superclass/instanceof edge cases)

Also fix readonly property test expectations to accept V8's native
error message with kNonMasking.
Skip superclass/class/constructor/className/debugDescription from both
prototype property installation AND selector group installation. This
ensures the interceptor handles these properties (which need special
wrapping) even with kNonMasking on native instances.

Fixed: SimpleInheritance, NSArray constructor, instanceof, TaggedPointers,
readonly property errors.

Remaining: 1 Swift class name test (constructor.name is empty string
instead of the mangled Swift class name).

Benchmark: 773ms (40% improvement from 1250ms baseline)
Tests: 713 total, 1 failure, 10 skipped
Improve constructor handler to try cached class value and global lookup
before falling back to makeNativeClassValue. Also skip className from
prototype installation.

Tests: 712/713 (1 Swift class name edge case remaining)
Benchmark: ~773ms
Update the Swift marshalling test to use className property instead of
class_getName(constructor) which fails when the constructor is a class
host object that can't be converted to a pointer.

Tests: 713/0
…object-arg fast path + cached invocation flags
…e interceptor (skips per-access metadata discovery for JSI engines)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants